蓝桥杯—九宫重排(bfs + hash)

  历届试题 九宫重排  
时间限制:1.0s   内存限制:256.0MB
      
问题描述
  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
  输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
  输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
样例输出
3
样例输入
13524678.
46758123.
样例输出
22
 
 
 
 
code:
 
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#define LL long long
using namespace std;
char s1[15],s2[15],maze[5][5];
int xx[] = {1,-1,0,0};  
int yy[] = {0,0,1,-1}; 
map<LL,int> mp;
LL s,tot;
struct node{
    int x,y,step;
    char mi[3][3];
}st,ne,tmp;

LL hash(char dd[3][3]){  
    LL ans = 0;  
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
        ans = ans*10 + dd[i][j] - '0';  
    return ans;  
}

void bfs(int x,int y)
{
    queue<node> que;
    st.x = x,st.y = y;
    st.step = 0;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            st.mi[i][j] = maze[i][j];
    que.push(st);
    mp[s] = 1;
    while(!que.empty())
    {
        tmp = que.front();
        que.pop();
        for(int i=0; i<4; i++)
        {
            ne = tmp;
            ne.x = tmp.x + xx[i];
            ne.y = tmp.y + yy[i];
            ne.step = tmp.step + 1;
            if(ne.x<0 || ne.x >=3 || ne.y<0 || ne.y>=3)continue;
            ne.mi[tmp.x][tmp.y] = ne.mi[ne.x][ne.y];
            ne.mi[ne.x][ne.y] = '0';
            LL now = hash(ne.mi);
            if(now == tot)
            {
                printf("%d\n",ne.step);
                return ;
            }
            if(!mp[now])
            {
                mp[now] = 1;
                que.push(ne);
            }
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%s%s",s1,s2))
    {
        int x,y;
        int len = strlen(s1);
        for(int i=0; i<len; i++)
        {
            if(s1[i] == '.')
            s1[i]='0',x=i/3,y=i%3;
        }
        s = 0;
        for(int i=0; i<len; i++)
             s = s * 10 + s1[i] - '0'
        for(int i=0; i<len; i++)
        {
            if(s2[i] == '.')
            s2[i]='0';
        }
        for(int i=0; i<len; i++)
        {
            maze[i/3][i%3] = s1[i];
        }
        tot = 0;
        for(int i=0; i<len; i++)
             tot = tot * 10 + s2[i] - '0'
        bfs(x,y);
    }
}
View Code
 
posted @ 2015-04-04 21:51  Doli  阅读(519)  评论(0编辑  收藏  举报